﻿using System;
using System.Collections.Generic;

using Perseus;

namespace Hetymine.Executioner.Data {
    public class ArgumentInfo {
        public ArgumentInfo() : this(string.Empty) { }
        public ArgumentInfo(string arguments) {
            this.RegularArguments = new List<string>();
            this.SpecialArguments = new Dictionary<string, List<string>>();

            SkipStringStream skip = new SkipStringStream();
            SkipItem skipItem = new SkipItem("\"", "\"", 1);
            skipItem.AddIgnoreString("\\\"");
            skip.AddSkipItem(skipItem);

            var args = arguments.Split(" ", skip, SplitOptions.RemoveEmptyEntries);

            foreach (string arg in args) {
                if (arg.StartsWith("@", StringComparison.Ordinal)) {
                    var argParts = arg.Split(":", SplitOptions.RemoveEmptyEntries);
                    string name = argParts[0].Substring(1); // Remove @ sign
                    this.SpecialArguments.Add(name, new List<string>());

                    if (argParts.Length > 1) {
                        for (int i = 1; i < argParts.Length; ++i) {
                            string ap;
                            if (argParts[i].EnclosedWith("\"", "\"", StringComparison.Ordinal)) {
                                ap = argParts[i].Substring(1, argParts[i].Length - 2);
                            }
                            else {
                                ap = argParts[i];
                            }
                            // Remove any escaped quotes or @ signs
                            ap = ap.Replace("\\\"", "\"").Replace("\\\\", "\\");

                            this.SpecialArguments[name].Add(ap);
                        }
                    }

                    continue;
                }

                // Regular argument
                string a;
                if (arg.EnclosedWith("\"", "\"", StringComparison.Ordinal)) {
                    a = arg.Substring(1, arg.Length - 2);
                }
                else {
                    a = arg;
                }
                // Remove any escaped quotes or @ signs
                a = a.Replace("\\\"", "\"").Replace("\\@", "@").Replace("\\\\", "\\");
                this.RegularArguments.Add(a);
            }
        }


        public List<string> RegularArguments { get; protected set; }
        public Dictionary<string, List<string>> SpecialArguments { get; protected set; }
        
        public override string ToString() {
            var s = new string[this.RegularArguments.Count + this.SpecialArguments.Count];
            
            int index = -1;
            
            foreach (string arg in this.RegularArguments) {
                ++index;
                if (arg.IndexOf(" ") >= 0) {
                    s[index] = "\"" + arg.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"";  
                }
                else {
                    s[index] = arg;
                }
            }

            // ex. @arg1:"param 1":param2 @arg2 @arg3:param1
            foreach (string key in this.SpecialArguments.Keys) {
                ++index;

                s[index] = "@" + key;
                if (this.SpecialArguments[key].Count > 0) {
                    foreach (string pram in this.SpecialArguments[key]) {
                        if (pram.IndexOf(" ") >= 0) {
                            s[index] += ":\"" + pram.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"";
                        }
                        else {
                            s[index] += ":" + pram;
                        }                        
                    }
                }
            }

            return s.Join(" ");
        }
    }
}
